﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Serialization;

[ExecuteInEditMode]
public class Model : MonoBehaviour
{
    [CompilerGenerated]
    private static Action<FrameAnimator.Frame> <>f__am$cacheB;
    public RuntimeAnimatorController controller;
    public FrameAnimator frameAnimator;
    public bool generateCollider;
    public bool isEditorGizmo;
    [SerializeField]
    private Vector3 offset;
    private Transform offsettedInstance;
    [SerializeField]
    private GameObject prefab;
    [HideInInspector]
    public string prefabFileName;
    [SerializeField, FormerlySerializedAs("prefab"), HideInInspector]
    private Transform prefabTsm;

    protected virtual void Awake()
    {
        if (Application.isPlaying && base.enabled)
        {
            if (this.isEditorGizmo && !GameUtility.isLevelEditorScene)
            {
                UnityEngine.Object.Destroy(this);
            }
            else if (this.instance == null)
            {
                this.instance = this.CreateInstance();
            }
        }
    }

    protected GameObject CreateInstance()
    {
        GameObject prefab = this.GetPrefab();
        if (prefab == null)
        {
            return null;
        }
        GameObject go = new GameObject(prefab.name);
        GameObject obj4 = UnityEngine.Object.Instantiate<GameObject>(prefab);
        obj4.transform.localPosition = this.offset;
        this.offsettedInstance = obj4.transform;
        obj4.gameObject.SetActive(true);
        obj4.gameObject.hideFlags = HideFlags.None;
        obj4.transform.parent = go.transform;
        go.SetParentAndResetTransform(base.gameObject);
        this.anim = obj4.GetComponentInChildren<Animator>();
        if ((this.anim != null) && (this.controller != null))
        {
            this.anim.runtimeAnimatorController = this.controller;
        }
        return go;
    }

    private void Destroy()
    {
        if (this.instance != null)
        {
            UnityEngine.Object.Destroy(this.instance.gameObject);
        }
    }

    public void GenerateCollider()
    {
        if (this.instance == null)
        {
            this.instance = this.CreateInstance();
        }
        this.generateCollider = true;
        this.GenerateCollider(this.instance);
    }

    private void GenerateCollider(GameObject target)
    {
        if (target != null)
        {
            foreach (MeshRenderer renderer in target.GetComponentsInChildren<MeshRenderer>(true))
            {
                MeshFilter component = renderer.GetComponent<MeshFilter>();
                if (component != null)
                {
                    component.gameObject.layer = base.gameObject.layer;
                    MeshCollider orAddComponent = component.GetOrAddComponent<MeshCollider>();
                    orAddComponent.sharedMesh = renderer.GetComponent<MeshFilter>().sharedMesh;
                    orAddComponent.gameObject.isStatic = base.gameObject.isStatic;
                }
            }
        }
    }

    public Vector3 GetOffset()
    {
        if (!Application.isPlaying)
        {
            return this.offset;
        }
        if (this.offsettedInstance == null)
        {
            return Vector3.zero;
        }
        return this.offsettedInstance.localPosition;
    }

    public GameObject GetPrefab()
    {
        if (this.prefab == null)
        {
            this.prefab = AssetManager.LoadModel(this.prefabFileName);
        }
        return this.prefab;
    }

    public FrameAnimator.Clip LoadClip(string clipName, bool loop = true)
    {
        FrameAnimator.Clip clip = (this.frameAnimator == null) ? null : this.frameAnimator.FindClip(clipName);
        if (clip == null)
        {
            Asset asset = this.GetAsset();
            string fileName = PathUtility.ChangeFileName(asset.modelFileName, asset.shortName + "@" + clipName);
            if (!AssetManager.HasModel(fileName))
            {
                return null;
            }
            FrameAnimator component = AssetManager.LoadModel(fileName).CloneAsChild(base.transform, true).GetComponent<FrameAnimator>();
            clip = component.GetClips().First<FrameAnimator.Clip>();
            clip.name = clipName;
            if (<>f__am$cacheB == null)
            {
                <>f__am$cacheB = delegate (FrameAnimator.Frame f) {
                    f.isActive = false;
                };
            }
            clip.frames.ForEach(<>f__am$cacheB);
            clip.loop = loop;
            if (this.frameAnimator == null)
            {
                this.frameAnimator = this.AddComponent<FrameAnimator>();
            }
            this.frameAnimator.AddClip(clip);
            UnityEngine.Object.Destroy(component);
            if (this.generateCollider)
            {
                this.GenerateCollider(base.gameObject);
            }
        }
        return clip;
    }

    private void OnDisable()
    {
        if (this.instance != null)
        {
            this.instance.gameObject.SetActive(false);
        }
    }

    private void OnEnable()
    {
        if (this.instance != null)
        {
            this.instance.gameObject.SetActive(true);
        }
    }

    public void PlayAnimation(string clipName)
    {
        this.LoadClip(clipName, false);
        if (this.frameAnimator != null)
        {
            base.enabled = false;
            this.frameAnimator.Play(clipName);
        }
    }

    public void SetInstanceActive(bool active)
    {
        if (this.instance != null)
        {
            this.instance.gameObject.SetActive(active);
        }
    }

    public void SetOffset(Vector3 value)
    {
        if (this.offsettedInstance != null)
        {
            this.offsettedInstance.localPosition = value;
        }
    }

    public void SetPrefab(GameObject value)
    {
        this.prefab = value;
    }

    [DebuggerHidden]
    private IEnumerator Start()
    {
        return new <Start>c__IteratorA { <>f__this = this };
    }

    public Animator anim { get; private set; }

    public GameObject instance { get; private set; }

    [CompilerGenerated]
    private sealed class <Start>c__IteratorA : IDisposable, IEnumerator, IEnumerator<object>
    {
        internal object $current;
        internal int $PC;
        internal Model <>f__this;
        internal AnimatorCullingMode <mode>__0;

        [DebuggerHidden]
        public void Dispose()
        {
            this.$PC = -1;
        }

        public bool MoveNext()
        {
            uint num = (uint) this.$PC;
            this.$PC = -1;
            switch (num)
            {
                case 0:
                    if (this.<>f__this.generateCollider)
                    {
                        this.<>f__this.GenerateCollider(this.<>f__this.instance);
                    }
                    if (this.<>f__this.anim == null)
                    {
                        break;
                    }
                    this.<mode>__0 = this.<>f__this.anim.cullingMode;
                    this.<>f__this.anim.cullingMode = AnimatorCullingMode.AlwaysAnimate;
                    this.$current = new WaitForSeconds(1f);
                    this.$PC = 1;
                    return true;

                case 1:
                    this.<>f__this.anim.cullingMode = this.<mode>__0;
                    break;

                default:
                    goto Label_00BC;
            }
            this.$PC = -1;
        Label_00BC:
            return false;
        }

        [DebuggerHidden]
        public void Reset()
        {
            throw new NotSupportedException();
        }

        object IEnumerator<object>.Current
        {
            [DebuggerHidden]
            get
            {
                return this.$current;
            }
        }

        object IEnumerator.Current
        {
            [DebuggerHidden]
            get
            {
                return this.$current;
            }
        }
    }
}

